#include<iostream>
using namespace std;

//类的继承也分为三种，public protected private
//三种方式对子类没有影响，对子类生成的对象有影响
//1、public继承 父类的public protected private成员，对于子类来说依旧是public protected private(子类除了private都可以访问)，子类的对象只能访问public（常用）
//2、protected继承 父类的public protected private成员，对于子类来说是protected protected private(子类除了private都可以访问)，子类的对象没法访问
//3、private继承 父类的public protected private成员，对于子类来说是private private private(子类除了private都可以访问)，子类的对象没法访问（默认是private）

class A
{
public:
    int a;
    A(){
        a1 = 1;
        a2 = 2;
        a3 = 3;
        a = 4;
    };

    void fun(){
        cout << a << endl;
        cout << a1 << endl;
        cout << a2 << endl;
        cout << a3 << endl;
    }

public :
    int a1;
protected:
    int a2;
private:
    int a3;
};

//1、public继承
class B : public A
{
public:
    int a;
    B(int i){
        A();
        a = i;
    };

    void fun(){
        cout << a << endl; //正确
        cout << a1 << endl;//正确
        cout << a2 << endl;//正确，子类可以访问父类的protected
        // cout << a3 << endl;//错误，子类不可以访问父类的private
    }
};

//2、protected继承
class C : protected A
{
public:
    int a;
    C(int i){
        A();
        a = i;
    };

    void fun(){
        cout << a << endl; //正确
        cout << a1 << endl;//正确
        cout << a2 << endl;//正确，子类可以访问父类的protected
        // cout << a3 << endl;//错误，子类不可以访问父类的private
    }
};

//3、private 继承
class D : private A
{
public:
    int a;
    D(int i){
        A();
        a = i;
    };

    void fun(){
        cout << a << endl; //正确
        cout << a1 << endl;//正确
        cout << a2 << endl;//正确，子类可以访问父类的protected
        // cout << a3 << endl;//错误，子类不可以访问父类的private
    }
};

int main(){
    B b(10);
    // b.fun();
    cout << b.a << endl; //正确，基类自己的public
    cout << b.a1 << endl;//正确
    // cout << b.a2 << endl;//错误，对象(类外)不能访问protected成员
    // cout << b.a3 << endl;//错误，对象(类外)不能访问private成员

    C c(20);
    // b.fun();
    cout << c.a << endl; //正确，基类自己的public
    // cout << c.a1 << endl;//错误，对象(类外)不能访问protected成员(a1在基类是public，但是被protected继承，在子类中就表现为protected)
    // cout << c.a2 << endl;//错误，对象(类外)不能访问protected成员
    // cout << c.a3 << endl;//错误，对象(类外)不能访问private成员

    D d(20);
    // b.fun();
    cout << d.a << endl; //正确，基类自己的public
    // cout << d.a1 << endl;//错误，对象(类外)不能访问private成员(a1在基类是public，但是被private继承，在子类中就表现为private)
    // cout << d.a2 << endl;//错误，对象(类外)不能访问private成员(a1在基类是protected，但是被private继承，在子类中就表现为private)
    // cout << d.a3 << endl;//错误，对象(类外)不能访问private成员

    return 0;
}